﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Rhino.Mocks;
using System.Web.Routing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Specialized;
using System.Web.DynamicData;

namespace ASPItalia.ModelVirtualCasting.Web.Tests.Utils
{
    public static class RouteTestHelper
    {
        public static RouteData GetRouteData(string url, Action<RouteCollection> action)
        {
            RouteCollection routeCollection =
                new RouteCollection();
            action(routeCollection);

            var context = RouteTestHelper.GetTestContext(url);

            return routeCollection.GetRouteData(context);
        }

        public static HttpContextBase GetTestContext(string url)
        {
            var mocks = new MockRepository();

            var context = mocks.Stub<HttpContextBase>(null);
            SetupResult.For(context.Request.AppRelativeCurrentExecutionFilePath).Return(url);
            SetupResult.For(context.Request.QueryString).Return(new NameValueCollection());

            context.Replay();

            return context;
        }

        public static void AssertRoute(RouteData routeData, string controller, string action)
        {
            Assert.IsNotNull(routeData, "Route is not mapped");

            Assert.AreEqual(controller, routeData.Values["controller"], "Controller is wrong");
            Assert.AreEqual(action, routeData.Values["action"], "Action is wrong");
        }

        public static void AssertRoute(RouteData routeData, string controller, string action, string id)
        {
            AssertRoute(routeData, controller, action);
            
            Assert.AreEqual(id, routeData.Values["id"], "Id is wrong");
        }

        public static void AssertNotMapped(RouteData routeData)
        {
            Assert.IsNull(routeData);
        }

        public static void AssertRoute(RouteData routeData, string controller, string action, object parameters)
        {
            AssertRoute(routeData, controller, action);

            AssertRoute(routeData, parameters);
        }

        public static void AssertRoute(RouteData routeData, object expectations)
        {
            Assert.IsNotNull(routeData, "Route is not mapped");

            foreach (var property in expectations.GetType().GetProperties())
            {
                Assert.AreEqual(
                    property.GetValue(expectations, null),
                    routeData.Values[property.Name],
                    string.Format("Parameter {0} is wrong", property.Name));
            }
        }

        public static void AssertIsIgnored(RouteData routeData)
        {
            Assert.IsNotNull(routeData, "Route is not mapped");

            Assert.IsInstanceOfType(routeData.RouteHandler, typeof(StopRoutingHandler));
        }
    }
}
